[FEATURE] Add OpenSearch datasource and log query plugin with PPL support#641
[FEATURE] Add OpenSearch datasource and log query plugin with PPL support#641Oliver-ke wants to merge 13 commits into
Conversation
Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
05cd7bf to
bc65cad
Compare
Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
The bound was being appended at the end of the user query, which fails once the user pipeline drops @timestamp from the schema (stats, fields, top). Tests now describe the intended ordering. Implementation follows. Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
…cker file Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
0963d7f to
496c296
Compare
Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
Signed-off-by: Azorji Kelechi Oliver <kelechioliver96@gmail.com>
…search-plugin chore(plugins): update with remote main branch
|
Hi @Oliver-ke, |
Sure, I'd share my testing.md file shortly |
|
TESTING.md Testing the OpenSearch pluginManual QA steps. Verifies datasource, log query, and trace → logs pivot. Prerequisites
1. Run unit testsInstall once at the workspace root so cd plugins
npm install
cd opensearch
npm test
npm run type-check
npm run lintValidate the plugin schemas with cd plugins/opensearch
percli plugin lint
percli plugin test-schemasGo SDK: cd plugins/opensearch
go test ./sdk/...Expect all green. No skipped suites. 2. Start a local OpenSearchUse the bundled compose file (also boots OpenSearch Dashboards on cd docs/examples
docker compose up -d
docker compose logs -f opensearch # watch boot, Ctrl+C once "started" appearsWait until ready: curl -s http://localhost:9200/_cluster/health | jq .statusExpect Teardown when done: docker compose down -v3. Seed sample log dataIndex two log documents with a shared curl -X POST "http://localhost:9200/otel-logs-2026.04.29/_doc" \
-H 'Content-Type: application/json' -d '{
"@timestamp": "2026-04-29T10:00:00Z",
"body": "request received",
"traceId": "abc123",
"severity": "INFO"
}'
curl -X POST "http://localhost:9200/otel-logs-2026.04.29/_doc" \
-H 'Content-Type: application/json' -d '{
"@timestamp": "2026-04-29T10:00:01Z",
"body": "request failed",
"traceId": "abc123",
"severity": "ERROR"
}'
curl -X POST "http://localhost:9200/otel-logs-2026.04.29/_refresh"Sanity-check PPL endpoint directly: curl -X POST "http://localhost:9200/_plugins/_ppl" \
-H 'Content-Type: application/json' \
-d '{"query":"source=otel-logs-* | where traceId='\''abc123'\''"}'Expect 2 datarows in response. 4. Build and serve the plugincd plugins/opensearch
npm run devDev server listens on 5. Register the datasource in PersesThe current Perses UI does not accept raw YAML for datasource creation, so create Option A — via the UI formNavigate to Admin → Global Datasources → Add Datasource. Fill in:
Save. Option B — via
|
| Case | Input | Expected |
|---|---|---|
| Empty query | `` | No request, no error toast |
| Bad PPL | source=foo | invalid |
Error banner with PPL error body (SyntaxCheckException) |
| Wrong index | source=does-not-exist |
Error banner with IndexNotFoundException from OpenSearch (the PPL endpoint returns 404; the plugin surfaces that as an OpenSearchPPLError) |
| Unreachable DS | stop docker, re-run query | Error banner, retry works after restart |
| Aggregation (stats) | source=otel-logs-* | stats count() by service |
Returns one row per service, no error |
| Field projection | source=otel-logs-* | fields service, body | head 10 |
Returns 10 rows with only those two columns |
7. Field overrides
Index a doc with non-standard field names:
curl -X POST "http://localhost:9200/legacy-logs/_doc" \
-H 'Content-Type: application/json' -d '{
"time": "2026-04-29T10:05:00Z",
"message": "legacy log line",
"trace_id": "abc123"
}'
curl -X POST "http://localhost:9200/legacy-logs/_refresh"In the query spec, set:
timestampField: time
messageField: message
query: source=legacy-logs | where trace_id='abc123'Expect row to render with time as timestamp and message as body. Without
the overrides, the row still renders without crashing: missing timestamp falls
back to epoch 0, and missing message falls back to a JSON dump of the row.
8. Trace → logs pivot
Load docs/examples/trace-to-logs.json as a dashboard. Requires a Tempo (or Jaeger) datasource also configured.
- Set
traceIdvariable toabc123. - Logs panel re-runs and shows the 2 seeded rows.
- Change variable to
xyz999. Logs panel goes empty without error. - Swap Tempo panel for Jaeger per
docs/examples/README.md. Logs panel unchanged.
9. Cleanup
cd plugins/opensearch/docs/examples
docker compose down -v
Description
Adds an OpenSearch datasource + log query plugin
These changes includes:
remaining columns (e.g. traceId) as labels.
queryError prop (parses error.reason / error.details from the OpenSearch error JSON).
opensearch/docs/examples/trace-to-logs.json (Tempo + OpenSearch; Jaeger swap documented).
and 2 Go tests (builder JSON shape + omitempty for optional fields).
Screenshots
DataSource

Checklist
[<catalog_entry>] <commit message>naming convention using one of thefollowing
catalog_entryvalues:FEATURE,ENHANCEMENT,BUGFIX,BREAKINGCHANGE,DOC,IGNORE.UI Changes